﻿using System.Collections.Generic;
using CcrFlows.Core;
using CcrFlows.Internal.Stages;
using Microsoft.Ccr.Core;

namespace CcrFlows.Stages
{
    internal abstract class IteratorStage<TIn, TOut> : StageBase
    {
        internal IteratorStage()
            : base(new[] { new Port<TIn>() }, new[] { new Port<TOut>() }) { }


        protected IEnumerator<ITask> ProcessIteratorHandler(TIn input, SeqIteratorHandler<TIn, TOut> handler, bool processSequentially)
        {
            {
                var pYield = new Port<EmptyValue>();
                var output = (Port<TOut>)base.outputPorts[0];

                IEnumerator<TOut> iterator = handler(input);
                while (iterator.MoveNext())
                {
                    output.Post(iterator.Current);

                    pYield.Post(EmptyValue.SharedInstance);
                    yield return pYield.Receive();
                }

                if (processSequentially) base.WaitForNextInput();
            }
        }
    }
}
